package com.server.auth.controller;

import cn.hutool.core.date.DateUtil;

import com.server.auth.service.AuthService;
import com.server.auth.vo.GetVerifyCodeVo;
import com.server.auth.dto.SmsLoginDto;
import com.server.model.all.user.bo.LoginBo;
import com.server.model.all.user.bo.SmsLoginBo;
import com.server.model.all.constant.token.TokenConstant;
import com.server.common.code.domain.VerifyCode;
import com.server.common.code.error.BusinessException;
import com.server.common.code.utils.*;
import com.server.common.code.vo.LoginVo;
import com.server.auth.dto.LoginDto;
import com.server.common.redis.token.TokenServices;
import com.server.common.redis.service.verify.RedisLoginVerifyService;
import com.server.common.redis.vo.TokenVo;
import com.server.common.security.code.SecurityUtils;
import com.server.common.security.code.anntation.Log;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

@RestController
@RequestMapping(path = "/userAuth")
@Slf4j
public class AuthController {

    @Resource
    private TokenServices tokenServices;


    @Resource
    private AuthService authService;

    @Resource
    private RedisLoginVerifyService redisLoginVerifyService;

    /**
     * 登录
     * @author LXC
     * @date 2022/4/27 22:31
     */
    @PostMapping(value = "/api/login")
    @ApiOperation(value = "登录")
    public Result<TokenVo> login(@RequestBody @Validated LoginDto loginDto) {
        LoginBo loginBo = BeanUtils.copyProperties(loginDto, LoginBo.class);
        TokenVo tokenVo = authService.login(loginBo);
        return ResultUtil.success(tokenVo,"登录成功");
    }

    /**
     * 短信验证码登录
     * @author LXC
     * @date 2022/6/22 23:04
     */
    @PostMapping(value = "/api/smsLogin")
    @ApiOperation(value = "短信验证码登录")
    public Result<TokenVo> smsLogin(@RequestBody @Validated SmsLoginDto smsLoginDto) {
        SmsLoginBo smsLoginBo = BeanUtils.copyProperties(smsLoginDto, SmsLoginBo.class);
        TokenVo tokenVo = authService.smsLogin(smsLoginBo);
        return ResultUtil.success(tokenVo,"登录成功");
    }

    /**
     * 获取验证图
     * @author LXC
     * @date 2022/9/11 11:41
     */
    @Log
    @GetMapping(value = "/api/getVerifyCode")
    @ApiOperation(value = "获取验证图")
    public Result<GetVerifyCodeVo> getVerifyCode() {
        VerifyCode verifyCode = VerifyCodeUtils.getImage();
        GetVerifyCodeVo getVerifyCodeVo = BeanUtils.copyProperties(verifyCode,GetVerifyCodeVo.class);

        redisLoginVerifyService.addLoginVerify(getVerifyCodeVo.getTextCode(), verifyCode.getTextValue());

        return ResultUtil.successData(getVerifyCodeVo);
    }


    /**
     * 退出
     * @author LXC
     * @date 2022/4/28 12:56
     */
    @PostMapping(value = "/outLogin")
    @ApiOperation(value = "退出登录")
    public Result<Boolean> outLogin() {
        Boolean deleteToken = tokenServices.deleteToken(SecurityUtils.getHeader(TokenConstant.TOKEN));

        if(!deleteToken){
            throw new BusinessException("退出登录失败,请重试");
        }

        return ResultUtil.successData(true);
    }


    /**
     * 续费Token
     * @author LXC
     * @date 2022/11/3 23:01
     */
    @PostMapping(value = "/renewalToken")
    @ApiOperation(value = "续费Token")
    public Result<TokenVo> renewalToken() {
        LoginVo loginVo = SecurityUtils.getLoginVo();
        String token = SecurityUtils.getHeader(TokenConstant.TOKEN);

        OptionalUtils.ofEmpty(loginVo).orElseThrow(()->new BusinessException("请求异常"));

        if(loginVo.getRenewalTime() <= DateUtil.current()){
            return ResultUtil.successData(tokenServices.refreshToken(token, loginVo));
        }

        TokenVo tokenVo = TokenVo.builder()
                .renewalTime(loginVo.getRenewalTime())
                .expireTime(loginVo.getExpireTime())
                .token(token)
                .build();

        return ResultUtil.successData(tokenVo);
    }


}
